In [1]:
import sys
import os
sys.path.insert(0, os.path.abspath('../'))
sys.path.insert(0, os.path.abspath('../../'))
sys.path.insert(0, os.path.abspath('/home/hm-tlacherm/qlm_notebooks/notebooks_1.2.1/notebooks/master_thesis_qaoa/'))
sys.path.insert(0, os.path.abspath('/home/hm-tlacherm/qlm_notebooks/notebooks_1.2.1/notebooks/master_thesis_qaoa/ibm/'))
In [2]:
import numpy as np

import qiskit
provider = qiskit.IBMQ.load_account()
from qiskit import Aer
from qiskit.utils import QuantumInstance
from qiskit_optimization.algorithms import MinimumEigenOptimizer
from qiskit.algorithms import QAOA
from shared.QiskitMaxcut import *
from ibm.ibm_parameters import *

from matplotlib import pyplot as plt
%matplotlib inline
In [3]:
graph = load_nx_graph_from("/home/hm-tlacherm/qlm_notebooks/notebooks_1.2.1/notebooks/master_thesis_qaoa/data/graphs/16_nodes/graph_16_33_01.txt")
max_cut = Maxcut(graph)
max_cut_qubo = max_cut.to_qubo()
print(graph.name)
max_cut.draw()
graph_16_33_01
In [4]:
step_size = 0.1
a_gamma = np.arange(0, np.pi, step_size)
b_beta = np.arange(0, np.pi, step_size)
In [5]:
a_gamma, b_beta = np.meshgrid(a_gamma, b_beta)
In [6]:
quantum_instance = QuantumInstance(
                    backend=Aer.get_backend(DEFAULT_QASM_SIMULATOR),
                    shots=SHOTS)
qaoa = QAOA(
            optimizer=COBYLA(maxiter=0),
            quantum_instance=quantum_instance,
            reps=1
            )

op, offset = max_cut_qubo.to_ising()
In [7]:
def maxcut_obj(x, G):
    """
    Given a bitstring as a solution, this function returns
    the number of edges shared between the two partitions
    of the graph.
    
    Args:
        x: str
           solution bitstring
           
        G: networkx graph
        
    Returns:
        obj: float
             Objective
    """
    obj = 0
    for i, j in G.edges():
        if x[i] != x[j]:
            obj -= 1
            
    return obj


def compute_expectation(counts, G):
    
    """
    Computes expectation value based on measurement results
    
    Args:
        counts: dict
                key as bitstring, val as count
           
        G: networkx graph
        
    Returns:
        avg: float
             expectation value
    """
    
    avg = 0
    sum_count = 0
    for bitstring, count in counts.items():
        
        obj = maxcut_obj(bitstring, G)
        avg += obj * count
        sum_count += count
        
    return avg/sum_count
In [8]:
def create_cirucit(gamma,beta):
    circuits = qaoa.construct_circuit([gamma,beta], operator=op)
    circuit = circuits[0]
    circuit.measure_all()
    return circuit
In [9]:
landscape = np.zeros(a_gamma.shape)

for i in range(0, len(landscape)):
    circuits = []
    for j in range(0, len(landscape)):
        # create circuits for entire row 
        circuit = create_cirucit(a_gamma[i][j], b_beta[i][j])
        circuits.append(circuit)
    
    # create one job with circuits 
    job_name = f"{graph.name}_row_{i}"
    job = qiskit.execute(circuits, backend=provider.get_backend('ibmq_mumbai'), shots=8000)
    job.update_name(job_name)
    print(job_name)
    
    # add results to landscape 
    j = 0
    for count in job.result().get_counts():
        mean = compute_expectation(count, graph)
        landscape[i,j] = mean
        j += 1
graph_16_33_01_row_0
graph_16_33_01_row_1
graph_16_33_01_row_2
graph_16_33_01_row_3
graph_16_33_01_row_4
graph_16_33_01_row_5
graph_16_33_01_row_6
graph_16_33_01_row_7
graph_16_33_01_row_8
graph_16_33_01_row_9
graph_16_33_01_row_10
graph_16_33_01_row_11
graph_16_33_01_row_12
graph_16_33_01_row_13
graph_16_33_01_row_14
graph_16_33_01_row_15
graph_16_33_01_row_16
graph_16_33_01_row_17
graph_16_33_01_row_18
graph_16_33_01_row_19
graph_16_33_01_row_20
graph_16_33_01_row_21
graph_16_33_01_row_22
graph_16_33_01_row_23
graph_16_33_01_row_24
graph_16_33_01_row_25
graph_16_33_01_row_26
graph_16_33_01_row_27
graph_16_33_01_row_28
graph_16_33_01_row_29
graph_16_33_01_row_30
graph_16_33_01_row_31
In [10]:
print(landscape)
plt.matshow(landscape)
plt.show()
[[-16.222625 -16.219625 -16.09775  ... -16.3585   -16.298    -16.240375]
 [-16.02375  -16.00375  -15.923    ... -16.23675  -16.081    -16.005125]
 [-15.945125 -15.969    -15.95175  ... -16.21975  -16.03825  -15.9735  ]
 ...
 [-15.833125 -15.822625 -15.8815   ... -15.972    -15.91     -15.8365  ]
 [-15.725625 -15.79325  -15.921875 ... -15.862625 -15.8615   -15.744   ]
 [-15.972375 -16.010375 -15.980875 ... -15.9575   -15.945375 -15.940375]]
In [11]:
# Mean of landscape
np.mean(landscape)
Out[11]:
-16.306847900390625
In [12]:
# Minimium 
np.min(landscape)
Out[12]:
-16.611
In [13]:
# Display Coordinates of Minimum 
np.unravel_index(np.argmin(landscape), landscape.shape)
Out[13]:
(27, 9)
In [14]:
# Gamma and beta value of Minimium
gamma, beta = np.unravel_index(np.argmin(landscape), landscape.shape)
opt_gamma = gamma * step_size
opt_beta = beta * step_size
print(f"Opt.Gamma: {opt_gamma}, Opt.Beta: {opt_beta}")
Opt.Gamma: 2.7, Opt.Beta: 0.9
In [15]:
# Save result matrix 
with open('landscape_mumbai_paper_no_weights_results.npy', 'wb') as f:
    np.save(f, landscape)
In [16]:
import plotly.graph_objects as go
In [17]:
# Plot landscape in 3D 
a_gamma = np.arange(0, np.pi, step_size)
b_beta = np.arange(0, np.pi, step_size)
fig = go.Figure(data=go.Surface(z=landscape, x=a_gamma, y=b_beta))

fig.update_traces(contours_z=dict(show=True, usecolormap=True, highlightcolor='limegreen', project_z=True))


fig.update_layout(title="QAOA MaxCut", scene=dict(
    xaxis_title="gamma",
    yaxis_title="beta",
    zaxis_title="mean"
))
In [18]:
# Plot Heatmap 
fig = go.Figure(data=go.Heatmap(z=landscape, x=b_beta, y=a_gamma, type = 'heatmap', colorscale = 'viridis'))

# Update Layout
fig.update_layout(title="QAOA MaxCut", width=700, height=700, xaxis_title="beta", yaxis_title="gamma")

# Display Global Minimium 
fig.add_trace(
    go.Scatter(mode="markers", x=[opt_beta], y=[opt_gamma], marker_symbol=[204], text = [landscape[gamma,beta]],
                   marker_color="red",  hovertemplate="x: %{x}<br>y: %{y}<br> z: %{text:.2f}<extra></extra>", 
                   marker_line_width=1, marker_size=16))
In [19]:
# Display Optimizer Results

# Display path 
#fig.add_trace(
#    go.Scatter(mode="lines", x=gammas, y=betas, marker_symbol=[200],
#                   marker_color="white", marker_line_width=1, marker_size=8)
#)

# Display start point
#fig.add_trace(
#    go.Scatter(mode="markers", x=[gammas[0]], y=[betas[0]], marker_symbol=[204],
#                   marker_color="gray", 
#                   marker_line_width=1, marker_size=16))

# Display end point
#fig.add_trace(
#    go.Scatter(mode="markers", x=[gammas[-1]], y=[betas[-1]], marker_symbol=[204],
#                   marker_color="green", 
#                   marker_line_width=1, marker_size=16))
In [20]:
# Plot Optimizer History
#fig = go.Figure(data=go.Scatter(x=counts, y=values))
#fig.update_layout(xaxis_title="Evaluation Counts", yaxis_title="Evaluated Mean", title="Optimizer")
#fig.show()
In [ ]: